<template>
  <div class="list-table">
    <el-form :inline="true">
      <el-form-item :label="$t('菜单名称')">
        <el-input v-model="queryParams.menuName" :placeholder="$t('菜单名称')" clearable size="small" @keyup.enter.native="handleQuery" />
      </el-form-item>
      <el-form-item :label="$t('状态')">
        <el-select v-model="queryParams.visible" :placeholder="$t('请选择')" clearable size="small">
          <el-option v-for="dict in visibleOptions" :key="dict.dictValue" :label="$t(dict.dictLabel)" :value="dict.dictValue" />
        </el-select>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">{{ $t("搜索") }}</el-button>
      </el-form-item>
    </el-form>
    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button v-hasPermi="['system:menu:edit']" type="primary" icon="el-icon-plus" size="mini" @click="handleAdd">{{ $t("新增") }}</el-button>
        <el-button v-hasPermi="['system:menu:edit']" icon="el-icon-check" plain size="mini" @click="submitSort">{{ $t('保存排序') }}</el-button>
      </el-col>
    </el-row>

    <el-table ref="table" v-loading="loading" border :data="menuList" row-key="menuId" :tree-props="{children: 'children', hasChildren: 'hasChildren'}" lazy :load="lazyLoad">
      <el-table-column prop="menuName" :label="$t('菜单名称')" :show-overflow-tooltip="true">
        <template slot-scope="scope">
          <span>{{ $t(scope.row.menuName) }}</span>
        </template>
      </el-table-column>
      <el-table-column prop="icon" :label="$t('图标')" align="center" width="100px">
        <template slot-scope="scope">
          <svg-icon :icon-class="scope.row.icon" />
        </template>
      </el-table-column>
      <el-table-column prop="orderNum" :label="$t('排序')" width="120px" align="center">
        <template slot-scope="scope">
          <el-input v-model="scope.row.orderNum" />
        </template>
      </el-table-column>
      <el-table-column prop="perms" :label="$t('权限标识')" :show-overflow-tooltip="true" />
      <el-table-column prop="component" :label="$t('组件路径')" :show-overflow-tooltip="true" />
      <el-table-column prop="visible" :label="$t('可见')" width="80px" align="center">
        <template slot-scope="scope">
          <el-switch
            v-model="scope.row.visible"
            active-value="0"
            inactive-value="1"
            @change="handleVisibleChange(scope.row)"
          />
        </template>
      </el-table-column>
      <el-table-column :label="$t('创建时间')" align="center" prop="createTime" width="180">
        <template slot-scope="scope">
          <span>{{ parseTime(scope.row.createTime) }}</span>
        </template>
      </el-table-column>
      <el-table-column :label="$t('操作')" align="center" width="250" class-name="small-padding fixed-width">
        <template slot-scope="scope">
          <el-button v-hasPermi="['system:menu:edit']" size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)">{{ $t('修改') }}</el-button>
          <el-button v-hasPermi="['system:menu:add']" size="mini" type="text" icon="el-icon-plus" @click="handleCopy(scope.row)">{{ $t('复制') }}</el-button>
          <el-button v-hasPermi="['system:menu:add']" size="mini" type="text" icon="el-icon-plus" @click="handleAdd(scope.row)">{{ $t("新增") }}</el-button>
          <el-button v-hasPermi="['system:menu:remove']" size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)">{{ $t('删除') }}</el-button>
        </template>
      </el-table-column>
    </el-table>
    <el-backtop target=".app-main" :bottom="10" class="menuSaveSort" @click="submitSort">
      <el-button v-hasPermi="['system:menu:edit']" type="primary">{{ $t('保存排序') }}</el-button>
    </el-backtop>

    <!-- 添加或修改菜单对话框 -->
    <el-dialog v-el-drag-dialog :title="$t('菜单')" :visible.sync="open" width="70%" class="dataForm" :close-on-click-modal="false" :lock-scroll="false">
      <div style="height: 450px;overflow: auto;padding: 20px;margin: -20px;">
        <el-form ref="form" :model="form" :rules="rules" label-width="80px">
          <el-row>
            <el-col :span="12">
              <el-form-item :label="$t('上级菜单')">
                <treeselect v-model="form.parentId" :options="menuOptions" :show-count="true" :placeholder="$t('请选择')">
                  <label slot="option-label" slot-scope="{ node, shouldShowCount, count, labelClassName, countClassName }" :class="labelClassName">
                    {{ $t(node.label) }}
                    <span v-if="shouldShowCount" :class="countClassName">({{ count }})</span>
                  </label>
                </treeselect>
              </el-form-item>
            </el-col>
            <el-col :span="12" style="height: 84px">
              <el-form-item :label="$t('菜单类型')" prop="menuType">
                <el-radio-group v-model="form.menuType">
                  <el-radio label="M">{{ $t('目录') }}</el-radio>
                  <el-radio label="C">{{ $t('菜单') }}</el-radio>
                  <el-radio label="F">{{ $t('页签') }}</el-radio>
                </el-radio-group>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item :label="$t('菜单图标')">
                <el-popover placement="bottom-start" width="460" trigger="click" @show="$refs['iconSelect'].reset()">
                  <IconSelect ref="iconSelect" @selected="selected" />
                  <el-input slot="reference" v-model="form.icon" :placeholder="$t('请选择')" readonly>
                    <svg-icon v-if="form.icon" slot="prefix" :icon-class="form.icon" class="el-input__icon" style="height: 32px;width: 16px;" />
                    <i v-else slot="prefix" class="el-icon-search el-input__icon" />
                  </el-input>
                </el-popover>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item :label="$t('菜单标识')" prop="menuKey">
                <el-input v-model="form.menuKey" :placeholder="$t('菜单标识')" />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item :label="$t('菜单名称')" prop="menuName">
                <el-input v-model="form.menuName" :placeholder="$t('菜单名称')" />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item :label="$t('显示排序')" prop="orderNum">
                <el-input-number v-model="form.orderNum" controls-position="right" :min="0" :max="9999" />
              </el-form-item>
            </el-col>

            <el-col :span="12">
              <el-form-item :label="$t('组件路径')" prop="component">
                <el-input v-model="form.component" :placeholder="$t('组件路径')" />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item :label="$t('权限标识')">
                <el-input v-model="form.perms" :placeholder="$t('权限标识')" :maxlength="50" />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item :label="$t('是否外链')">
                <el-radio-group v-model="form.isFrame">
                  <el-radio label="0">{{ $t('是') }}</el-radio>
                  <el-radio label="1">{{ $t('否') }}</el-radio>
                </el-radio-group>
              </el-form-item>
            </el-col>

            <el-col :span="12">
              <el-form-item :label="$t('菜单状态')">
                <el-radio-group v-model="form.visible">
                  <el-radio v-for="dict in visibleOptions" :key="dict.dictValue" :label="dict.dictValue">{{ $t(dict.dictLabel) }}</el-radio>
                </el-radio-group>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item :label="$t('菜单图标Logo')">
                <UploadAvatar :logo-info="form.logoInfo" @appendData="uploadImg($event)" />
              </el-form-item>
            </el-col>
            <!--  菜单权限 -->
            <el-col :span="24">
              <div style="margin: 10px auto;display: inline-block;width:100%;">
                <div class=" area-header">
                  <span class="area-header-title">{{ $t('菜单权限') }}</span>
                </div>
                <el-table :data="form.permissionList" border class="formTable">
                  <el-table-column :label="$t('序号')" align="center" type="index" width="50" />
                  <el-table-column :show-overflow-tooltip="true">
                    <template slot="header" slot-scope="{}">
                      <i style="color: #ff4949;margin-right: 4px;">*</i><span>{{ $t('名称') }}</span>
                    </template>
                    <template slot-scope="scope">
                      <el-form-item :prop="'permissionList.' + scope.$index + '.name'" :rules="rules.name">
                        <el-input v-model="scope.row.name" />
                      </el-form-item>

                    </template>
                  </el-table-column>
                  <el-table-column :show-overflow-tooltip="true">
                    <template slot="header" slot-scope="{}">
                      <i style="color: #ff4949;margin-right: 4px;">*</i><span>{{ $t('权限标签') }}</span>
                    </template>
                    <template slot-scope="scope">
                      <el-form-item :prop="'permissionList.' + scope.$index + '.permission'" :rules="rules.permission">
                        <el-input v-model="scope.row.permission" />
                      </el-form-item>

                    </template>
                  </el-table-column>
                  <el-table-column :label="$t('排序')" prop="sort">
                    <template slot-scope="scope">
                      <el-input-number v-model="scope.row.sort" controls-position="right" :precision="0" />
                    </template>
                  </el-table-column>
                  <el-table-column :label="$t('操作')" align="center" width="50" class-name="small-padding fixed-width">
                    <template slot-scope="scope">
                      <el-button size="mini" type="text" icon="el-icon-delete" @click="delPermission(scope.$index, scope.row)" />
                    </template>
                  </el-table-column>
                </el-table>

                <div class="tol">
                  <el-button type="primary" icon="el-icon-plus" size="mini" @click="AddRow">{{ $t("添加") }}</el-button>
                </div>
              </div>
            </el-col>

          </el-row>
        </el-form>
      </div>

      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitForm">{{ $t("确定") }}</el-button>
        <el-button @click="cancel">{{ $t("取消") }}</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import {
  listMenu,
  getMenu,
  treeselect,
  delMenu,
  saveMenu,
  submitSort,
  uploadAvatar,
  handleVisibleChangeServer
} from '@/api/system/menu'
  import Treeselect from '@riophae/vue-treeselect'
  import '@riophae/vue-treeselect/dist/vue-treeselect.css'
  import IconSelect from '@/components/IconSelect'
  import UploadAvatar from '@/components/Avatar/uploadAvatar'
  export default {
    name: 'Menu',
    components: {
      Treeselect,
      IconSelect,
      UploadAvatar
    },

    data() {
      return {
        // 遮罩层
        loading: true,
        // 菜单表格树数据
        menuList: [],
        // 菜单树选项
        menuOptions: [],
        // 是否显示弹出层
        open: false,
        // 菜单状态数据字典
        visibleOptions: [],
        // 查询参数
        queryParams: {
          menuName: undefined,
          visible: undefined,
          scene: '1',
          parentId: 0
        },
        // 表单参数
        form: {
          // 菜单权限
          permissionList: []
        },
        // 表单校验
        rules: {
          menuName: [{
            required: true,
            message: this.$t('必填信息'),
            trigger: 'blur'
          }],
          orderNum: [{
            required: true,
            message: this.$t('必填信息'),
            trigger: 'blur'
          }],
          name: [{
            required: true,
            message: this.$t('必填信息'),
            trigger: 'blur'
          }],
          permission: [{
            required: true,
            message: this.$t('必填信息'),
            trigger: 'blur'
          }]
        },
        menuNodeMaps: new Map(),
        menuParentId: undefined
      }
    },
    created() {
      this.getList()
      this.getDicts('sys_show_hide').then(response => {
        this.visibleOptions = response.data
      })
    },

    methods: {
      lazyLoad(row, treeNode, resolve) {
        var query = {
          parentId: row.id,
          scene: this.queryParams.scene,
          menuName: this.queryParams.menuName,
          visible: this.queryParams.visible
        }
        listMenu(query).then(response => {
          // response.data.forEach(item => {
          //   item.hasChildren = true
          // })
          resolve(response.data)
          this.menuNodeMaps.set(row.id, { row, treeNode, resolve })
        })
      },
      // 刷新树形结构缓存
      refreshLoad(parentId) {
        // 根据父级ID取出对应节点数据
        if (parentId === 0 || parentId === '0') {
          this.getList()
        } else if (parentId === undefined || parentId === '' || parentId === null) {
          this.$set(this.$refs.table.store.states, 'lazyTreeNodeMap', {})
          this.menuList = []
        } else {
          var menuMap = this.menuNodeMaps.get(parentId)
          if (menuMap) {
            const { row, treeNode, resolve } = this.menuNodeMaps.get(parentId)
            this.$set(this.$refs.table.store.states.lazyTreeNodeMap, parentId, [])
            if (row) {
              // 将取出对应数据再传给load方法，重新加载数据。
              this.lazyLoad(row, treeNode, resolve)
            }
          }
        }
      },
      AddRow() {
        const row = {
          name: '',
          permission: '',
          sort: this.form.permissionList.length + 1
        }
        if (this.form.component) {
          switch (this.form.permissionList.length) {
            case 0:
              row.name = '编辑'
              row.permission = this.form.component.split('/')[0] + ':' + this.form.component.split('/')[1] + ':edit'
              break
            case 1:
              row.name = '删除'
              row.permission = this.form.component.split('/')[0] + ':' + this.form.component.split('/')[1] + ':remove'
              break
            case 2:
              row.name = '导出'
              row.permission = this.form.component.split('/')[0] + ':' + this.form.component.split('/')[1] + ':export'
              break
          }
        }
        this.form.permissionList.push(row)
      },
      handleEdit(index, row) {
        console.log(index, row)
      },

      // 删除行
      delPermission(index) {
        this.form.permissionList.splice(index, 1)
      },

      // 选择图标
      selected(name) {
        this.form.icon = name
      },
      /** 查询菜单列表 */
      getList() {
        this.loading = true
        if (this.$refs.table && this.$refs.table.store) {
          this.$refs.table.store.states.lazyTreeNodeMap = {}
          this.$refs.table.store.states.treeData = []
        }
        listMenu(this.queryParams).then(response => {
          this.menuList = response.data
          this.loading = false
        })
      },
      /** 查询菜单下拉树结构 */
      getTreeselect() {
        treeselect().then(response => {
          this.menuOptions = []
          const menu = {
            id: 0,
            label: this.$t('主类目'),
            children: []
          }
          menu.children = response.data
          this.menuOptions.push(menu)
        })
      },
      // 菜单显示状态字典翻译
      visibleFormat(row) {
        if (row.menuType === 'F') {
          return ''
        }
        return this.selectDictLabel(this.visibleOptions, row.visible)
      },
      // 显示/隐藏菜单快捷
      handleVisibleChange(row) {
        const text = row.visible === '0' ? this.$t('显示') : this.$t('隐藏')
        this.$confirm(this.$t('确认要') + text + '?', this.$t('警告'), {
          confirmButtonText: this.$t('确定'),
          cancelButtonText: this.$t('取消'),
          type: 'warning'
        }).then(function() {
          return handleVisibleChangeServer(row.id, row.visible)
        }).then(() => {
          this.msgSuccess(text + this.$t('成功'))
        }).catch(function() {
          row.visible = row.visible === '0' ? '1' : '0'
        })
      },
      // 取消按钮
      cancel() {
        this.open = false
        this.form.copyId = undefined
        this.reset()
      },
      // 表单重置
      reset() {
        this.form = {
          menuId: undefined,
          menuKey: undefined,
          parentId: 0,
          menuName: undefined,
          icon: undefined,
          menuType: 'M',
          orderNum: undefined,
          isFrame: '1',
          visible: '0',
          permissionList: [],
          logoInfo: ''
        }
        this.resetForm('form')
      },
      /** 搜索按钮操作 */
      handleQuery() {
        this.getList()
      },
      /** 新增按钮操作 */
      handleAdd(row) {
        this.reset()
        this.getTreeselect()
        this.form.copyId = undefined
        if (row != null) {
          this.form.parentId = row.menuId
        }
        this.open = true

        // if (this.form.menuType === 'M') {
        // 		this.$set(this.form, 'component', 'system/log/index')
        // }
      },
      /** 修改按钮操作 */
      handleUpdate(row) {
        this.reset()
        this.getTreeselect()
        this.form.copyId = undefined
        getMenu(row.menuId).then(response => {
          this.form = response.data
          // 备份上级菜单id
          this.menuParentId = response.data.parentId
          // 菜单权限
          // this.form.permissionList = response.data.permissionList;
          this.open = true
        })
      },
      /** 提交按钮 */
      submitForm: function() {
        this.$refs['form'].validate(valid => {
          if (valid) {
            this.form.scene = '1'
            saveMenu(this.form).then(response => {
              if (response.code === 200) {
                if (this.form.copyId !== undefined && this.form.copyId !== null) {
                  this.msgSuccess(this.$t('复制成功'))
                } else {
                  this.msgSuccess(this.$t('修改成功'))
                }
                this.open = false
                this.form.copyId = undefined
                this.refreshLoad(this.form.parentId)
                if (this.menuParentId) {
                  this.refreshLoad(this.menuParentId)
                }
                this.menuParentId = undefined
                // this.getList()
              } else {
                this.msgError(response.msg)
              }
            })
          } else {
            this.locationError(document)
          }
        })
      },
      /** 删除按钮操作 */
      handleDelete(row) {
        this.$confirm(this.$t('是否确认删除?') + row.menuName + '?', this.$t('警告'), {
          confirmButtonText: this.$t('确定'),
          cancelButtonText: this.$t('取消'),
          type: 'warning'
        }).then(function() {
          return delMenu(row.menuId)
        }).then(() => {
          this.refreshLoad(row.parentId)
          this.refreshLoad()
          // this.getList()
          this.msgSuccess(this.$t('删除成功'))
        }).catch(function() {})
      },
      // 保存排序
      // 保存排序
      submitSort() {
        var data = {}
        data.menuList = []
        // 保存传值时只传ID和排序
        for (let i = 0; i < this.menuList.length; i++) {
          data.menuList.push({ orderNum: this.menuList[i].orderNum, id: this.menuList[i].id })
          data.menuList = data.menuList.concat(this.obtainChildren(this.$refs.table.store.states.lazyTreeNodeMap[this.menuList[i].id]))
        }
        this.loading = true
        submitSort(data).then(response => {
          if (response.code === 200) {
            this.refreshLoad()
            this.getList()
            this.loading = false
            this.msgSuccess(this.$t('修改成功'))
          } else {
            this.msgError(response.msg)
          }
        })
      },
      // 获取子节点
      obtainChildren(children) {
        var childrenArray = []
        if (children !== undefined) {
          for (let i = 0; i < children.length; i++) {
            childrenArray.push({ orderNum: children[i].orderNum, id: children[i].id })
            childrenArray = childrenArray.concat(this.obtainChildren(this.$refs.table.store.states.lazyTreeNodeMap[children[i].id]))
          }
        }
        return childrenArray
      },
      // 上传图片
      uploadImg(data) {
        const formData = new FormData()
        formData.append('avatarfile', data)
        formData.append('id', this.form.id)
        uploadAvatar(formData).then(response => {
          if (response.code === 200) {
            this.form.logoInfo = response.msg
            this.msgSuccess(this.$t('修改成功'))
            this.$refs.uploadAvatar.open = false
          } else {
            this.msgError(response.msg)
          }
        })
      },
      handleCopy(row) {
        this.reset()
        this.getTreeselect()
        getMenu(row.menuId).then(response => {
          this.form = response.data
          this.form.id = undefined
          this.form.copyId = row.id
          this.open = true
        })
      }
    }

  }
</script>
